package com.ef.web.action;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;

import com.ef.constant.ConfirmMessage;
import com.ef.constant.EContractState;
import com.ef.constant.ELeadsStatus;
import com.ef.constant.StatusType;
import com.ef.domain.ClassLevel;
import com.ef.domain.ClassType;
import com.ef.domain.ClassUnit;
import com.ef.domain.Contract;
import com.ef.domain.Course;
import com.ef.domain.Gift;
import com.ef.domain.Leads;
import com.ef.domain.Material;
import com.ef.domain.PayHistory;
import com.ef.service.ClassLevelService;
import com.ef.service.ClassTypeService;
import com.ef.service.ContractService;
import com.ef.service.CourseService;
import com.ef.service.GiftService;
import com.ef.service.LeadsService;
import com.ef.service.MaterialService;
import com.ef.service.PayService;
import com.ef.util.CustomExample;
import com.ef.util.PaginationSupport;

public class ContractAction extends BaseAction<Contract> {

	private static final long serialVersionUID = 1L;

	private ContractService contractService;

	private ClassLevelService classLevelService;

	private CourseService courseService;

	private GiftService giftService;

	private MaterialService materialService;

	private ClassTypeService classTypeService;

	private LeadsService leadsService;
	/**
	 * 可行的ClassType
	 */
	private List<ClassType> optionalClassTypeList;

	private List<ClassUnit> selectClassUnitList;

	private Map<String, String> beginLevelList;

	private Map<String, String> courseList;

	private Map<String, String> allGifts;

	private Map<String, String> allMaterials;

	private Map<String, String> selectedGifts;

	private Map<String, String> selectedMaterials;

	private String selgifts;

	private String selmaterials;

	private String selBeginLevelId;

	private String selCourseId;

	private String selLeadsId;

	private List<PayHistory> payHistoryList;

	private PayService payService;

	private String leadsName;

	private String leadsTel;

	private Date selCreateStartTime;

	private Date selCreateEndTime;

	private Date selCommitStartTime;

	private Date selCommitEndTime;

	private Date selFinishStartTime;

	private Date selFinishEndTime;

	private Date selBeginStartTime;

	private Date selBeginEndTime;

	private Date selEndStartTime;

	private Date selEndEndTime;

	public String clean() {
		fetchListData();
		this.listResult = new PaginationSupport<Contract>(
				new ArrayList<Contract>(), 0);
		return LIST;
	}

	@SuppressWarnings("serial")
	public String list() {
		this.listResult = contractService.findByExample(
				new CustomExample<Contract>(this.getModel()) {
					public void appendCondition(Criteria criteria) {
						if ((leadsName != null && leadsName.trim().length() > 0)
								|| ((leadsTel != null && leadsTel.trim()
										.length() > 0))) {
							criteria.createAlias("leads", "leads");
							if (leadsName != null
									&& leadsName.trim().length() > 0) {
								criteria.add(Restrictions.like(
										"leads.name", leadsName.trim(),
										MatchMode.ANYWHERE));
							}
							if (leadsTel != null
									&& leadsTel.trim().length() > 0) {
								Disjunction or = Restrictions.disjunction();
								Property myProperty = Property
										.forName("leads.telephone");
								or.add(myProperty.like(leadsTel.trim(),
										MatchMode.ANYWHERE));
								myProperty = Property
										.forName("leads.mobileTelephone");
								or.add(myProperty.like(leadsTel.trim(),
										MatchMode.ANYWHERE));
								myProperty = Property
										.forName("leads.companyTelephone");
								or.add(myProperty.like(leadsTel.trim(),
										MatchMode.ANYWHERE));
								myProperty = Property
										.forName("leads.otherTelephone");
								or.add(myProperty.like(leadsTel.trim(),
										MatchMode.ANYWHERE));
								criteria.add(or);
							}
						}
						criteria.addOrder(Order.desc("updateTime"));
						criteria.add(Restrictions
								.eq("status", StatusType.VALID));
						this.addBetweenDateProperty("createTime",
								selCreateStartTime, selCreateEndTime);
						this.addBetweenDateProperty("commitTime",
								selCommitStartTime, selCommitEndTime);
						this.addBetweenDateProperty("finishTime",
								selFinishStartTime, selFinishEndTime);
						this.addBetweenDateProperty("startTime",
								selBeginStartTime, selBeginEndTime);
						this.addBetweenDateProperty("endTime", selEndStartTime,
								selEndEndTime);
						appendBetweenDateProperty(criteria);
						this.excludeProperty("isVip");
						this.enableLike(MatchMode.ANYWHERE);
					}
				}, this.getStartIndex(), this.getPageSize());
		return LIST;
	}

	public boolean canInvalidOrFinish(){
		if (this.getModel().getContractState()!=null){
			return getModel().getContractState().equals(EContractState.COMMIT);
		}
		return false;
	}
	private void fetchListData() {
		Map<String, String> map = new LinkedHashMap<String, String>();
		List<ClassLevel> classLevel = classLevelService.findALL();
		for (ClassLevel cl : classLevel) {
			map.put(cl.getId().toString(), cl.getName());
		}
		beginLevelList = map;

		Map<String, String> map2 = new LinkedHashMap<String, String>();
		List<Course> courses = courseService.findALL();
		for (Course c : courses) {
			map2.put(c.getId().toString(), c.getName());
		}
		courseList = map2;

		allGifts = new LinkedHashMap<String, String>();
		List<Gift> gfs = giftService.findALLVaild();
		for (Gift gf : gfs) {
			allGifts.put(gf.getId().toString(), gf.getName());
		}

		allMaterials = new LinkedHashMap<String, String>();
		List<Material> mats = materialService.findALLVaild();
		for (Material mat : mats) {
			allMaterials.put(mat.getId().toString(), mat.getName());
		}

		selectedGifts = new LinkedHashMap<String, String>();
		if (this.getModel() != null && this.getModel().getGifts() != null) {
			List<Gift> tgifts = this.getModel().getGifts();
			for (Gift gift : tgifts) {
				selectedGifts.put(gift.getId().toString(), gift.getName());
			}
		}
		selectedMaterials = new LinkedHashMap<String, String>();
		if (this.getModel() != null && this.getModel().getMaterials() != null) {
			List<Material> tMaterials = this.getModel().getMaterials();
			for (Material material : tMaterials) {
				selectedMaterials.put(material.getId().toString(), material
						.getName());
			}
		}

		List<ClassType> allClassTypelist = classTypeService.findALLValid();
		if (this.getModel().getId() != null
				&& this.getModel().getClassUnits() != null) {
			selectClassUnitList = this.getModel().getClassUnits();
			for (ClassUnit cu : selectClassUnitList) {
				allClassTypelist.remove(cu.getClassType());
			}
			optionalClassTypeList = allClassTypelist;
		} else {
			optionalClassTypeList = allClassTypelist;
			selectClassUnitList = new ArrayList<ClassUnit>();
		}
		if (this.getModel().getId() != null
				&& this.getModel().getCourse() != null) {
			this.selCourseId = this.getModel().getCourse().getId().toString();
		}
		if (this.getModel().getId() != null
				&& this.getModel().getBeginLevel() != null) {
			this.selBeginLevelId = this.getModel().getBeginLevel().getId()
					.toString();
		}
		if (this.getModel().getId() != null
				&& this.getModel().getLeads() != null) {
			this.selLeadsId = this.getModel().getLeads().getId().toString();
		}

		if (this.getModel().getId() != null) {
			payHistoryList = payService.findByContract(this.getModel());
		}
	}

	public String edit() {
		fetchListData();
		return EDIT;
	};

	public String finish() {
		StringBuffer respon = new StringBuffer();
		Contract cont = this.getModel();
		if (cont.getContractState() != null) {
			if (cont.getContractState().equals(EContractState.NEW)) {
				respon.append("ERROR: ContractNo:")
						.append(cont.getContractNo()).append(
								"is New ,Can't Finish! ").append(" ");
				this.resultError(respon.toString(), "list");
			} else if (cont.getContractState().equals(EContractState.COMMIT)) {
				Leads leads = cont.getLeads();
				leads.setIsStudent(false);
				leadsService.saveOrUpdate(leads);
				cont.setFinishTime(new Date());
				cont.setFinishUser(getSessionUser());
				cont.setContractState(EContractState.FINISHED);
				cont.setUpdateUser(getSessionUser());
				cont.setUpdateTime(new Date());
				contractService.saveOrUpdate(cont);
				this.resultOK("finish the contract", "list");
			}
		} else {
			respon.append("ERROR: ContractNo:").append(cont.getContractNo())
					.append("hasn't state! ").append(" ");
			this.resultError(respon.toString(), "list");
		}
		fetchListData();
		return VIEW;
	}

	public String invalid() {
		StringBuffer respon = new StringBuffer();
		Contract cont = this.getModel();
		if (cont.getContractState() != null) {
			if (cont.getContractState().equals(EContractState.NEW)) {
				respon.append("ERROR: ContractNo:")
						.append(cont.getContractNo()).append(
								"is New ,Can't Invalid! ").append(" ");
				this.resultError(respon.toString(), "list");
			} else if (cont.getContractState().equals(EContractState.COMMIT)) {
				Leads leads = cont.getLeads();
				leads.setIsStudent(false);
				leadsService.saveOrUpdate(leads);
				cont.setFinishTime(new Date());
				cont.setFinishUser(getSessionUser());
				cont.setContractState(EContractState.INVALID);
				cont.setUpdateUser(getSessionUser());
				cont.setUpdateTime(new Date());
				contractService.saveOrUpdate(cont);
 				this.resultOK("invalid the contract", "list");
			}
		} else {
			respon.append("ERROR: ContractNo:").append(cont.getContractNo())
					.append("hasn't state! ").append(" ");
			this.resultError(respon.toString(), "list");
		}
		fetchListData();
		return VIEW;
	}

	public String commit() {
		if (getSessionUser().getRole().getName().toUpperCase().equals("CC")) {
			return NONE;
		}
//		List<Contract> contracts = contractService.findDuplicateContract(this
//				.getModel().getId(), Long.valueOf(selLeadsId.trim()));
//		if (contracts != null && contracts.size() > 0) {
//			Contract cont = contracts.get(0);
//			String rsp = "this student has unfinish contract no :"
//					+ cont.getContractNo();
//			this.resultError(rsp, "list");
//			fetchListData();
//			return EDIT;
//		}

		Contract contract = this.getModel();
		if (contract.getLeads() == null) {// 新建
			contract.setContractState(EContractState.NEW);
			contract.setCreateTime(new Date());
			contract.setCreateUser(this.getSessionUser());
		}
		contract.setLeads(leadsService
				.findById(Long.valueOf(selLeadsId.trim())));
		List<Material> mats = null;
		if (this.getSelmaterials() != null
				&& this.getSelmaterials().trim().length() > 0) {
			String[] ms = this.getSelmaterials().trim().split(",");
			mats = new ArrayList<Material>();
			for (String m : ms) {
				mats.add(materialService.findById(Long.valueOf(m.trim())));
			}
		}
		contract.setMaterials(mats);
		List<Gift> gfs = null;
		if (this.getSelgifts() != null
				&& this.getSelgifts().trim().length() > 0) {
			String[] gs = this.getSelgifts().trim().split(",");
			gfs = new ArrayList<Gift>();
			for (String g : gs) {
				gfs.add(giftService.findById(Long.valueOf(g.trim())));
			}
		}
		contract.setGifts(gfs);
		String classUnitString = getRequest().getParameter("classUnitString");
		ArrayList<ClassUnit> classUnits = null;
		if (classUnitString != null && classUnitString.trim().length() > 0) {
			classUnits = new ArrayList<ClassUnit>();
			String[] cidLimit = classUnitString.split(";");
			for (String cl : cidLimit) {
				String[] c = cl.split(",");
				ClassUnit unit = new ClassUnit();
				unit.setClassType(classTypeService.findById(Long.valueOf(c[0]
						.trim())));
				unit.setUpdateLimitTimes(Integer.valueOf(c[1].trim()));
				classUnits.add(unit);
			}
		}
		contract.setClassUnits(classUnits);
		if (selBeginLevelId != null && selBeginLevelId.trim().length() > 0) {
			contract.setBeginLevel(classLevelService.findById(Long
					.valueOf(selBeginLevelId.trim())));
		}
		if (selCourseId != null && selCourseId.trim().length() > 0) {
			contract.setCourse(courseService.findById(Long.valueOf(selCourseId
					.trim())));
		}
		// contract.setUpdateTime(new Date());
		// contract.setUpdateUser(getSessionUser());
		contract.setCommitTime(new Date());
		contract.setCommitUser(this.getSessionUser());
		contract.setContractState(EContractState.COMMIT);
		contract.setUpdateUser(getSessionUser());
		contract.setUpdateTime(new Date());
		contractService.saveOrUpdate(contract);
		Leads leads = contract.getLeads();
//		if (contract.getFreeF2FTimes() != null) {
//			leads.setFreeF2FCount(contract.getFreeF2FTimes());
//		}
//		leads.setClassUnits(classUnits);
//		leads.setCurrentlevel(contract.getBeginLevel());
// 		leads.setEliteCard(contract.getEliteCard());
//		leads.setIsVIP(contract.getIsVip());
// 		leads.setStudent(true);
//		leads.setNeedJudgeNetLevel(contract.getCourse().getHasNetCourse());
//		leads.setValidStartTime(contract.getStartTime());
//		leads.setTrueValidStartTime(contract.getStartTime());
//		leads.setValidEndTime(contract.getEndTime());
//		leads.setTrueValidEndTime(contract.getEndTime());
// 		leads.setIsStudent(true);
//		if (selCourseId != null && selCourseId.trim().length() > 0) {
//			leads.setCourse(courseService.findById(Long.valueOf(selCourseId
//					.trim())));
//		}
		leads.setLeadsStatus(ELeadsStatus.Pay);
		leads.setPayTime(new Date());
		leadsService.saveOrUpdate(leads);
		fetchListData();
		return VIEW;
	}

	public String delete() {
		String ids = getRequest().getParameter("ids");
		String[] id = ids.split(",");
		StringBuffer respon = new StringBuffer();
		for (String i : id) {
			Contract cont = contractService.findById(Long.valueOf(i.trim()));
			if (cont.getContractState().equals(EContractState.NEW)) {
				contractService.delete(cont);
			} else if (cont.getContractState().equals(EContractState.COMMIT)
					|| cont.getContractState().equals(EContractState.FINISHED)) {
				respon.append("ERROR: ContractNo:")
						.append(cont.getContractNo()).append(
								"is " + cont.getContractState()
										+ "  ,Can't Delete! ").append(" ");
				this.resultError(respon.toString(), "list");
			}
		}
		return DELETE;
	}

	public String view() {
		fetchListData();
		return VIEW;
	}

	public String save() {

//		List<Contract> contracts = contractService.findDuplicateContract(this
//				.getModel().getId(), Long.valueOf(selLeadsId.trim()));
//		if (contracts != null && contracts.size() > 0) {
//			Contract cont = contracts.get(0);
//			String rsp = "this student has unfinish contract no :"
//					+ cont.getContractNo();
//			this.resultError(rsp, "list");
//			fetchListData();
//			return EDIT;
//		}

		Contract contract = this.getModel();
		if (contract.getLeads() == null) {// 新建
			contract.setContractState(EContractState.NEW);
			contract.setCreateTime(new Date());
			contract.setCreateUser(this.getSessionUser());
		}
		contract.setLeads(leadsService
				.findById(Long.valueOf(selLeadsId.trim())));
		List<Material> mats = null;
		if (this.getSelmaterials() != null
				&& this.getSelmaterials().trim().length() > 0) {
			String[] ms = this.getSelmaterials().trim().split(",");
			mats = new ArrayList<Material>();
			for (String m : ms) {
				mats.add(materialService.findById(Long.valueOf(m.trim())));
			}
		}
		contract.setMaterials(mats);
		List<Gift> gfs = null;
		if (this.getSelgifts() != null
				&& this.getSelgifts().trim().length() > 0) {
			String[] gs = this.getSelgifts().trim().split(",");
			gfs = new ArrayList<Gift>();
			for (String g : gs) {
				gfs.add(giftService.findById(Long.valueOf(g.trim())));
			}
		}
		contract.setGifts(gfs);
		String classUnitString = getRequest().getParameter("classUnitString");
		ArrayList<ClassUnit> classUnits = null;
		if (classUnitString != null && classUnitString.trim().length() > 0) {
			classUnits = new ArrayList<ClassUnit>();
			String[] cidLimit = classUnitString.split(";");
			for (String cl : cidLimit) {
				String[] c = cl.split(",");
				ClassUnit unit = new ClassUnit();
				unit.setClassType(classTypeService.findById(Long.valueOf(c[0]
						.trim())));
				unit.setUpdateLimitTimes(Integer.valueOf(c[1].trim()));
				classUnits.add(unit);
			}
		}
		contract.setClassUnits(classUnits);
		if (selBeginLevelId != null && selBeginLevelId.trim().length() > 0) {
			contract.setBeginLevel(classLevelService.findById(Long
					.valueOf(selBeginLevelId.trim())));
		}
		if (selCourseId != null && selCourseId.trim().length() > 0) {
			contract.setCourse(courseService.findById(Long.valueOf(selCourseId
					.trim())));
		}
	    contract.setUpdateTime(new Date());
		contract.setUpdateUser(getSessionUser());
		contractService.saveOrUpdate(contract);
		this.setResult(ConfirmMessage.Contract);
		fetchListData();
		return EDIT;
	};

	public ContractService getContractService() {
		return contractService;
	}

	public void setContractService(ContractService contractService) {
		this.contractService = contractService;
	}

	public ClassLevelService getClassLevelService() {
		return classLevelService;
	}

	public void setClassLevelService(ClassLevelService classLevelService) {
		this.classLevelService = classLevelService;
	}

	public Map<String, String> getBeginLevelList() {
		return beginLevelList;
	}

	public void setBeginLevelList(Map<String, String> beginLevelList) {
		this.beginLevelList = beginLevelList;
	}

	public CourseService getCourseService() {
		return courseService;
	}

	public void setCourseService(CourseService courseService) {
		this.courseService = courseService;
	}

	public Map<String, String> getCourseList() {
		return courseList;
	}

	public void setCourseList(Map<String, String> courseList) {
		this.courseList = courseList;
	}

	public GiftService getGiftService() {
		return giftService;
	}

	public void setGiftService(GiftService giftService) {
		this.giftService = giftService;
	}

	public MaterialService getMaterialService() {
		return materialService;
	}

	public void setMaterialService(MaterialService materialService) {
		this.materialService = materialService;
	}

	public String getSelgifts() {
		return selgifts;
	}

	public void setSelgifts(String selgifts) {
		this.selgifts = selgifts;
	}

	public String getSelmaterials() {
		return selmaterials;
	}

	public void setSelmaterials(String selmaterials) {
		this.selmaterials = selmaterials;
	}

	public Map<String, String> getAllGifts() {
		return allGifts;
	}

	public void setAllGifts(Map<String, String> allGifts) {
		this.allGifts = allGifts;
	}

	public Map<String, String> getAllMaterials() {
		return allMaterials;
	}

	public void setAllMaterials(Map<String, String> allMaterials) {
		this.allMaterials = allMaterials;
	}

	public Map<String, String> getSelectedGifts() {
		return selectedGifts;
	}

	public void setSelectedGifts(Map<String, String> selectedGifts) {
		this.selectedGifts = selectedGifts;
	}

	public Map<String, String> getSelectedMaterials() {
		return selectedMaterials;
	}

	public void setSelectedMaterials(Map<String, String> selectedMaterials) {
		this.selectedMaterials = selectedMaterials;
	}

	public List<ClassType> getOptionalClassTypeList() {
		return optionalClassTypeList;
	}

	public void setOptionalClassTypeList(List<ClassType> optionalClassTypeList) {
		this.optionalClassTypeList = optionalClassTypeList;
	}

	public List<ClassUnit> getSelectClassUnitList() {
		return selectClassUnitList;
	}

	public void setSelectClassUnitList(List<ClassUnit> selectClassUnitList) {
		this.selectClassUnitList = selectClassUnitList;
	}

	public ClassTypeService getClassTypeService() {
		return classTypeService;
	}

	public void setClassTypeService(ClassTypeService classTypeService) {
		this.classTypeService = classTypeService;
	}

	public String getSelBeginLevelId() {
		return selBeginLevelId;
	}

	public void setSelBeginLevelId(String selBeginLevelId) {
		this.selBeginLevelId = selBeginLevelId;
	}

	public String getSelCourseId() {
		return selCourseId;
	}

	public void setSelCourseId(String selCourseId) {
		this.selCourseId = selCourseId;
	}

	public LeadsService getLeadsService() {
		return leadsService;
	}

	public void setLeadsService(LeadsService leadsService) {
		this.leadsService = leadsService;
	}

	public String getSelLeadsId() {
		return selLeadsId;
	}

	public void setSelLeadsId(String selLeadsId) {
		this.selLeadsId = selLeadsId;
	}

	public List<PayHistory> getPayHistoryList() {
		return payHistoryList;
	}

	public void setPayHistoryList(List<PayHistory> payHistoryList) {
		this.payHistoryList = payHistoryList;
	}

	public PayService getPayService() {
		return payService;
	}

	public void setPayService(PayService payService) {
		this.payService = payService;
	}

	public String getLeadsName() {
		return leadsName;
	}

	public void setLeadsName(String leadsName) {
		this.leadsName = leadsName;
	}

	public String getLeadsTel() {
		return leadsTel;
	}

	public void setLeadsTel(String leadsTel) {
		this.leadsTel = leadsTel;
	}

	public Date getSelCreateStartTime() {
		return selCreateStartTime;
	}

	public void setSelCreateStartTime(Date selCreateStartTime) {
		this.selCreateStartTime = selCreateStartTime;
	}

	public Date getSelCreateEndTime() {
		return selCreateEndTime;
	}

	public void setSelCreateEndTime(Date selCreateEndTime) {
		this.selCreateEndTime = selCreateEndTime;
	}

	public Date getSelBeginStartTime() {
		return selBeginStartTime;
	}

	public void setSelBeginStartTime(Date selBeginStartTime) {
		this.selBeginStartTime = selBeginStartTime;
	}

	public Date getSelBeginEndTime() {
		return selBeginEndTime;
	}

	public void setSelBeginEndTime(Date selBeginEndTime) {
		this.selBeginEndTime = selBeginEndTime;
	}

	public Date getSelEndStartTime() {
		return selEndStartTime;
	}

	public void setSelEndStartTime(Date selEndStartTime) {
		this.selEndStartTime = selEndStartTime;
	}

	public Date getSelEndEndTime() {
		return selEndEndTime;
	}

	public void setSelEndEndTime(Date selEndEndTime) {
		this.selEndEndTime = selEndEndTime;
	}

	public Date getSelCommitStartTime() {
		return selCommitStartTime;
	}

	public void setSelCommitStartTime(Date selCommitStartTime) {
		this.selCommitStartTime = selCommitStartTime;
	}

	public Date getSelCommitEndTime() {
		return selCommitEndTime;
	}

	public void setSelCommitEndTime(Date selCommitEndTime) {
		this.selCommitEndTime = selCommitEndTime;
	}

	public Date getSelFinishStartTime() {
		return selFinishStartTime;
	}

	public void setSelFinishStartTime(Date selFinishStartTime) {
		this.selFinishStartTime = selFinishStartTime;
	}

	public Date getSelFinishEndTime() {
		return selFinishEndTime;
	}

	public void setSelFinishEndTime(Date selFinishEndTime) {
		this.selFinishEndTime = selFinishEndTime;
	}

}
